{***************************************************************************}
{                                                                           }
{           Spring Framework for Delphi                                     }
{                                                                           }
{           Copyright (C) 2009-2011 DevJET                                  }
{                                                                           }
{           http://www.spring4d.org                                         }
{                                                                           }
{***************************************************************************}
{                                                                           }
{  Licensed under the Apache License, Version 2.0 (the "License");          }
{  you may not use this file except in compliance with the License.         }
{  You may obtain a copy of the License at                                  }
{                                                                           }
{      http://www.apache.org/licenses/LICENSE-2.0                           }
{                                                                           }
{  Unless required by applicable law or agreed to in writing, software      }
{  distributed under the License is distributed on an "AS IS" BASIS,        }
{  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
{  See the License for the specific language governing permissions and      }
{  limitations under the License.                                           }
{                                                                           }
{***************************************************************************}

/// NOT READY
unit Spring.Configuration experimental;

{$I Spring.inc}

interface

uses
  Classes,
  SysUtils,
  Rtti,
  Generics.Collections,
  Spring,
  Spring.Collections,
  Spring.Configuration.ConfigurationProperty;

type

  IConfiguration = interface;
  IConfigurationSource = interface;
  IConfigurations = interface;

  {$REGION 'Documentation'}
  ///	<summary>Interface of a single configuration node (section), used to
  ///	traverse/manage/publish configuration tree</summary>
  {$ENDREGION}
  IConfiguration = interface
    ['{E37F5A2C-D792-4FA8-9DB7-A00FE0D7E76D}']
  {$REGION 'Property Accessors'}
    function GetName: string;
    procedure SetName(const newName: string);
    function GetParent: IConfiguration;
    function GetProperties: IDictionary<string, TConfigurationProperty>;
    function GetChildren: IConfigurations;
  {$ENDREGION}
    function TryGetProperty(const propertyKey: string; out requestedProperty: TConfigurationProperty): Boolean;

    {$REGION 'Documentation'}
    ///	<summary>Returns node property</summary>
    ///	<param name="propertyKey">Key of a requested property</param>
    ///	<exception cref="EConfigurationError">Thrown when there is no requested
    ///	property in node</exception>
    {$ENDREGION}
    function GetProperty(const propertyKey: string): TConfigurationProperty;

    {$REGION 'Documentation'}
    ///	<summary>Tries to find child node</summary>
    ///	<param name="childName">Name of requested child node</param>
    ///	<param name="requestedChild">Reference to found child node (or NULL, when
    ///	child node is not found)</param>
    {$ENDREGION}
    function TryGetChild(const childName: string;
      out requestedChild: IConfiguration): Boolean;

    {$REGION 'Documentation'}
    ///	<summary>Returns child node</summary>
    ///	<param name="childName">Name of requested child node</param>
    ///	<exception cref="EConfigurationException">Thrown when node does not
    ///	contain child with given name</exception>
    {$ENDREGION}
    function GetChild(const childName: string): IConfiguration;

    {$REGION 'Documentation'}
    ///	<summary>Unique identifier of a node (in single parent's
    ///	scope)</summary>
    {$ENDREGION}
    property Name: string read GetName write SetName;

    {$REGION 'Documentation'}
    ///	<summary>Reference to the parent node</summary>
    ///	<remarks>That property can be NULL!</remarks>
    {$ENDREGION}
    property Parent: IConfiguration read GetParent;

    {$REGION 'Documentation'}
    ///	<summary>String-indexed dictionary of configuration node properties -
    ///	the core of configuration data input/output interface</summary>
    ///	<remarks>Note that the Properties dictionary's default indexed property
    ///	( <i><b>Items[key: string]: IConfiguration</b></i> ) behaves
    ///	differently to standard Delphi/Spring dictionaries. The difference
    ///	shows up when one try to get item never added to the dictionary -
    ///	standard dictionaries are throwing an exception in such case. In case
    ///	of Properties collection there is no exception and requested item is
    ///	created and added to dictionary on the fly. All other dictionary
    ///	properties works as in standard dictionaries.</remarks>
    {$ENDREGION}
    property Properties: IDictionary<string, TConfigurationProperty> read GetProperties;

    {$REGION 'Documentation'}
    ///	<summary>Adds single child configuration node (subnode)</summary>
    {$ENDREGION}
    function AddChild: IConfiguration;

    {$REGION 'Documentation'}
    ///	<summary>Collection of child configuration nodes (subnodes), allows to
    ///	iterate thru them and removing them</summary>
    {$ENDREGION}
    property Children: IConfigurations read GetChildren;
  end;

  IConfigurationSource = interface
    ['{1443C8DF-D07D-4DAC-9509-FB79F375C557}']
    function GetConfiguration: IConfiguration;
    function TryGetConfiguration(out configuration: IConfiguration): Boolean;
  end;

  IConfigurable = interface
    ['{FCB399EF-F27C-44E1-BB9C-1723BB1D4830}']
    procedure Configure(const configuration: IConfiguration);
  end;

  IConfigurations = interface(IEnumerable<IConfiguration>)
  ['{CEA7FD09-3547-4104-B14C-861B34B16A0B}']
    function Remove(const item: IConfiguration): boolean; overload;
    procedure RemoveRange(const collection: array of IConfiguration); overload;
    procedure RemoveRange(const collection: IEnumerable<IConfiguration>); overload;
    procedure RemoveRange(const collection: TEnumerable<IConfiguration>); overload;
    procedure Clear;
  end;

implementation

end.
